package se.ytterman.jserial.framework.device;

import java.lang.*;
import java.util.*;
import java.util.concurrent.*;
import java.io.*;
import java.util.regex.*;

import se.ytterman.jserial.framework.device.*;

import se.ytterman.jserial.util.BinaryDumpUtil;
import se.ytterman.jserial.io.CommunicationAdapter;

public class DeviceOutputThread extends Thread {

    public DeviceOutputThread(CommunicationAdapter communicationsAdapter,
                              ResponseFactory responseFactory,
                              PriorityBlockingQueue responseQueue) {
	// Set interface reference
	this.communicationsAdapter = communicationsAdapter;

	this.responseFactory = responseFactory;    
        
        // Initialize reference to inbound queue
        this.responseQueue = responseQueue;
    }

    //--------------------------------------------------------------------
    // 
    //--------------------------------------------------------------------

    //--------------------------------------------------------------------
    // Poller thread body
    //--------------------------------------------------------------------

    public void run() {
        // Create input buffer
        ByteArrayOutputStream inputBuffer = new ByteArrayOutputStream();
        
	// Read forever...
	while(1 == 1) {           
	    // Store to buffer
            byte[] byteBuffer = this.communicationsAdapter.read();
            
            // Write written bytes into shift buffer, checking for
            // each byte if we have content matching a response
	    for(int byteIndex = 0; byteIndex < byteBuffer.length; byteIndex++) {                     
                // Write byte to shift buffer, shiftin one step left
                inputBuffer.write(byteBuffer[byteIndex]);
                
                // DEBUG BinaryDumpUtil.printCleanString(inputBuffer.toByteArray(), System.out);
                
                // See if we can match a new response
                Response newResponse = this.responseFactory.newResponse(inputBuffer);                    
                
                // We got a match!
                if(newResponse != null) {
                    // Put response into response queue
                    this.responseQueue.put(newResponse);
                    
                    // Clean input buffer
                    inputBuffer.reset();
                }
            }
	}
    }

    private CommunicationAdapter communicationsAdapter;  
    private ResponseFactory responseFactory;
    private PriorityBlockingQueue <Response> responseQueue;
}
